﻿using System;
using System.Linq;
using System.Globalization;
namespace System.Xml.Linq {
#if NET3 || NET4
	/// <summary>
	/// Extensions methods for XElement.
	/// </summary>
	public static class XElementExtensions {
		#region Public
		/// <summary>
		/// Gets the element value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <returns>Value or String.Empty</returns>
		public static String GetElementValue(this XElement node, XName name) {
			XElement child = node.Element(name);

			if (child != null && !String.IsNullOrEmpty(child.Value)) {
				return child.Value;
			}
			return String.Empty;
		}
		/// <summary>
		/// Gets the value of an attribute.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name of an attribute.</param>
		/// <returns>Value, or String.Empty</returns>
		public static String GetAttributeValue(this XElement node, XName name) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			if (node.HasAttributes) {
				XAttribute attribute = node.Attribute(name);
				if (attribute != null) {
					return attribute.Value;
				}
			}
			return String.Empty;
		}

		/// <summary>
		/// Tries to get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">The result.</param>
		/// <returns>True, if operation was success.</returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out double result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}
		/// <summary>
		/// Tries to get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">The result.</param>
		/// <returns>True, if operation was success.</returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out float result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}
		/// <summary>
		/// Tries to get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">The result.</param>
		/// <returns>True, if operation was success.</returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out ushort result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}
		/// <summary>
		/// Tries to get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">The result.</param>
		/// <returns>True, if operation was success.</returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out uint result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}
		/// <summary>
		/// Tries to get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">The result.</param>
		/// <returns>True, if operation was success.</returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out ulong result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}
		/// <summary>
		/// Tries to get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">The result.</param>
		/// <returns>True, if operation was success.</returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out short result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}
		/// <summary>
		/// Tries to get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">The result.</param>
		/// <returns>True, if operation was success.</returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out int result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}
		/// <summary>
		/// Tries to get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">The result.</param>
		/// <returns>True, if operation was success.</returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out long result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}
		/// <summary>
		/// Tries to get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">if set to <c>true</c> [result].</param>
		/// <returns></returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out bool result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}
		/// <summary>
		/// Tries the get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">The result.</param>
		/// <returns>True, if operation was success.</returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out DateTime result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}
		/// <summary>
		/// Tries the get attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="result">The result.</param>
		/// <returns>True, if operation was success.</returns>
		public static bool TryGetAttributeValue(this XElement node, XName name, out Guid result) {
			if (node == null) {
				throw new ArgumentNullException("node");
			}
			return Parser.TryParse(node.GetAttributeValue(name), out result);
		}

		/// <summary>
		/// Sets the attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="value">The value.</param>
		public static void SetAttributeValue(this XElement node, XName name, double value) {
			node.SetAttributeValue(name, value.ToString(NumberFormatInfo.InvariantInfo));
		}
		/// <summary>
		/// Sets the attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="value">The value.</param>
		public static void SetAttributeValue(this XElement node, XName name, float value) {
			node.SetAttributeValue(name, value.ToString(NumberFormatInfo.InvariantInfo));
		}
		/// <summary>
		/// Sets the attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="value">The value.</param>
		public static void SetAttributeValue(this XElement node, XName name, ushort value) {
			node.SetAttributeValue(name, value.ToString(NumberFormatInfo.InvariantInfo));
		}
		/// <summary>
		/// Sets the attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="value">The value.</param>
		public static void SetAttributeValue(this XElement node, XName name, uint value) {
			node.SetAttributeValue(name, value.ToString(NumberFormatInfo.InvariantInfo));
		}
		/// <summary>
		/// Sets the attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="value">The value.</param>
		public static void SetAttributeValue(this XElement node, XName name, ulong value) {
			node.SetAttributeValue(name, value.ToString(NumberFormatInfo.InvariantInfo));
		}
		/// <summary>
		/// Sets the attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="value">The value.</param>
		public static void SetAttributeValue(this XElement node, XName name, short value) {
			node.SetAttributeValue(name, value.ToString(NumberFormatInfo.InvariantInfo));
		}
		/// <summary>
		/// Sets the attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="value">The value.</param>
		public static void SetAttributeValue(this XElement node, XName name, int value) {
			node.SetAttributeValue(name, value.ToString(NumberFormatInfo.InvariantInfo));
		}
		/// <summary>
		/// Sets the attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="value">The value.</param>
		public static void SetAttributeValue(this XElement node, XName name, long value) {
			node.SetAttributeValue(name, value.ToString(NumberFormatInfo.InvariantInfo));
		}
		/// <summary>
		/// Sets the attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="value">The value.</param>
		public static void SetAttributeValue(this XElement node, XName name, DateTime value) {
			node.SetAttributeValue(name, value.ToString(NumberFormatInfo.InvariantInfo));
		}
		/// <summary>
		/// Sets the attribute value.
		/// </summary>
		/// <param name="node">The node.</param>
		/// <param name="name">The name.</param>
		/// <param name="value">The value.</param>
		public static void SetAttributeValue(this XElement node, XName name, Guid value) {
			node.SetAttributeValue(name, value.ToString());
		}
		#endregion
	}
#endif
}
